/**
 * 
 */
package se.ricardo.gamesorgs.client.modes.games;

import java.awt.BorderLayout;
import java.awt.LayoutManager;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JTable;

import se.ricardo.gamesorgs.api.common.ListTypes;
import se.ricardo.gamesorgs.api.request.GamesOptionsRequest;
import se.ricardo.gamesorgs.common.graphics.OptionsPanel;
import se.ricardo.gamesorgs.client.controllers.GamesController.OptionsChangedListener;
import se.ricardo.gamesorgs.client.modes.games.GamesPanel.GamesTableModel;
import se.ricardo.gamesorgs.database.models.GameContainer;


/**
 * This class creates a view for usage with the MVC design pattern.<br>
 * Creates a {@link JPanel} composed of other panels, for displaying
 * the games lists and options to the user.
 * <br>
 * 
 * @author Ricardo Ocaña Leal
 *
 */
public class MainGamesPanel extends JPanel {
	// Panels included in this main panel.
	private OptionsPanel optionsPanel;
	private GamesPanel gamesPanel;
	
	/**
	 * Sets the {@link LayoutManager} to {@link BorderLayout},
	 * and adds all the necessary panels.
	 * */
	public MainGamesPanel() {
		setLayout(new BorderLayout());
		
		optionsPanel = new OptionsPanel();
		add(optionsPanel, BorderLayout.WEST);
		
		gamesPanel = new GamesPanel();
		add(gamesPanel, BorderLayout.CENTER);
	}
	
	/**
	 * Called when the panel is first shown,
	 * so that the first item in the company list is selected.
	 * */
	public void init() {
		gamesPanel.tabbedPanel.setSelectedIndex(0);
		optionsPanel.setCompanyIndex(0);
	}
	
	/**
	 * Adds a listener to the various options components.
	 * <br>
	 * 
	 * @param
	 * l {@link OptionsChangedListener} for registering events.
	 * */
	public void registerListeners(OptionsChangedListener l) {
		gamesPanel.tabbedPanel.addChangeListener(l);
		optionsPanel.registerItemListener(l);
	}
	
	/**
	 * Updates a {@link GamesOptionsRequest} with the currently
	 * selected options in the panels.
	 * <br>
	 * 
	 * @param
	 * request The request to store the options values in.
	 * */
	public void updateOptionsRequest(GamesOptionsRequest request) {
		request.setSystemsIndex(optionsPanel.getSystemsIndex());
		request.setSystem(optionsPanel.getSystem());
		request.setCompanyIndex(optionsPanel.getCompanyIndex());
		request.setCompany(optionsPanel.getCompany());
		request.setListType(gamesPanel.getSelectedTabIndex());
	}
	
	/**
	 * Updates the companies {@link JList} with new data.
	 * <br>
	 * 
	 * @param
	 * companies {@link List} containing the data.
	 * */
	public void updateCompanies(List<String> companies) {
		DefaultListModel<String> companyModel = optionsPanel.getCompanyListModel();
		companyModel.removeAllElements();
		
		for(String s : companies) {
			companyModel.addElement(s);
		}
	}
	
	/**
	 * Updates the systems {@link JList} with new data.
	 * <br>
	 * 
	 * @param
	 * systems {@link List} containing the data.
	 * */
	public void updateSystems(Map<String, Integer> systems, int index) {
		DefaultListModel<String> systemModel = optionsPanel.getSystemsListModel();
		DefaultListModel<Integer> amountModel = optionsPanel.getAmountListModel();
		systemModel.removeAllElements();
		amountModel.removeAllElements();
		
		// Clear the games since they are not valid for the
		// currently selected company.
		clearGamesList();
		
		for(String s : systems.keySet()) {
			systemModel.addElement(s);
			amountModel.addElement(systems.get(s));
		}
		
		// If there are any available systems, set the first
		// item in the list to selected.
		// This will also trigger an update of the games list.
		if(systems.size() > 0) {
			optionsPanel.setSystemsIndex(index);
		}
	}
	
	/**
	 * Updates the currently selected {@link JTable} with new data.
	 * <br>
	 * 
	 * @param
	 * games {@link List} with {@link GameContainer} games.
	 * */
	public void updateGames(List<GameContainer> games) {
		GamesTableModel tableModel =
				(GamesTableModel)gamesPanel.getCurrentTableModel();
		tableModel.setData(games);
		tableModel.fireTableDataChanged();
	}
	
	/**
	 * Clears the currently selected {@link JTable} of all the data.
	 * */
	private void clearGamesList() {
		GamesTableModel tableModel = 
				(GamesTableModel)gamesPanel.getCurrentTableModel();
		tableModel.clearData();
		tableModel.fireTableDataChanged();
	}
	
	/**
	 * Returns a reference to the {@link GameContainer} object that is
	 * currently selected.
	 * <br>
	 * 
	 * @return
	 * Reference to a {@link GameContainer} object.
	 * */
	public GameContainer getSelectedGame() {
		GamesTableModel tableModel = (GamesTableModel)gamesPanel.getCurrentTableModel();
		int index = gamesPanel.getSelectedGameIndex();
		
		return tableModel.getGameAt(index);
	}
}
